﻿////什么是原子操作？
////原子操作是指在计算机系统中不可中断的操作。这种操作要么完全执行，要么完全不执行，不存在部分执行的情况。原子操作在多线程环境中尤其重要，因为它们能确保数据的完整性和一致性。
////举个例子，假设有两个线程同时对一个变量进行加一操作，如果这个加一操作不是原子的，那么可能会出现这样的情况：线程1读取变量的值，然后线程2也读取变量的值，然后线程1将变量加一，然后线程2也将变量加一。这样，虽然加一操作执了两次，但变量的值只增加了一，因为两个线程读取的都是原始值。
////如果加一操作是原子的，那么在一个线程执行加一操作时，其他线程将无法访问该变量，直到加一操作完成。这样，每个线程都会看到最新的值，变量的值会正确地增加两次。
////在编程中，原子操作通常通过特殊的指令或者通过锁来实现。例如，在C++中，标准库提供了一系列的原子类型，如std::atomic_int，可以用来进行原子操作。
//int sum = 0;

////AddOne();
////AddOne();
////AddOne();
////AddOne();
////AddOne();

//for(int i = 0; i < 5; i++)
//{
//    Thread thread = new Thread(AddOne);
//    thread.Start();
//}

//Thread.Sleep(1000);

////Interlocked 类
////Interlocked 为多个线程共享的变量提供原子操作。
////使用 Interlocked 类 避免竞争条件，可以在不阻塞线程(lock、Monitor)的情况下，对目标对象做修改。
////Interlocked.Exchange()  Exchange<T>(T, T)有针对引用类型的重载
////public static int Exchange(ref int location1, int value);  意思是将 value 赋给 location1 ，然后返回 location1 改变之前的值。

//Console.WriteLine(sum);

////volatile关键字 关键字指示一个字段可以由多个同时执行的线程修改。 出于性能原因，编译器，运行时系统甚至硬件都可能重新排列对存储器位置的读取和写入。

//void AddOne()
//{
//    for (int i = 0; i < 1000000; i++)
//    {
//        //sum += 1;
//        Interlocked.Add(ref sum, 1);
//    }
//}

int obj = 0;
Task.Run(() =>
{
    for (var i = 0; i < 100000000; i++)
    {
        obj++;
    }
});

Task.Run(() =>
{
    for (var i = 0; i < 100000000; i++)
    {
        obj++;
    }
});
Thread.Sleep(2000);
Console.WriteLine(obj);